package org.lanlab.storode.service;

import org.lanlab.storode.controller.request.NewPageRequest;
import org.lanlab.storode.dal.entity.Page;
import org.lanlab.storode.dal.entity.Requirement;
import org.lanlab.storode.dal.repository.PageRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
 * @author dove
 * @since 2020/1/9 14:18
 */
@Service
public class PageService {

    private final static Logger log = LoggerFactory.getLogger(PageService.class);
    private final PageRepository pageRepository;
    private final RequirementService requirementService;

    public PageService(PageRepository pageRepository,
                       RequirementService requirementService) {
        this.pageRepository = pageRepository;
        this.requirementService = requirementService;
    }

    @Transactional(rollbackFor = {Exception.class})
    public Page addPage(NewPageRequest newPageRequest) {
        log.info("[PageService]new page save request: {}", newPageRequest);
        Page page = convertPageRequestToPage(newPageRequest);
        page.setCreateTime(LocalDateTime.now());
        page.setUpdateTime(LocalDateTime.now());
        Page savedPage = pageRepository.save(page);
        List<Requirement> requirements = newPageRequest.getRequirements()
                .stream().map(requirementService::insertRequirement).collect(Collectors.toList());
        requirements.forEach(requirement ->
                linkRequirementToPage(savedPage.getId(), requirement.getRequirementNo()));
        log.info("[PageService]new page saved into database: {}", savedPage);
        return page;
    }

    public boolean linkRequirementToPage(Long pageId, String requirementNo) {
        return pageRepository.savePageRequirement(pageId, requirementNo);
    }

    public List<Requirement> getRequirementByPageId(Long pageId) {
        return pageRepository.listRequirementsByPageId(pageId);
    }

    private Page convertPageRequestToPage(NewPageRequest newPageRequest) {
        Page page = new Page();
        page.setTitle(newPageRequest.getTitle());
        page.setDetail(newPageRequest.getDetail());
        page.setParentId(newPageRequest.getParentId());
        return page;
    }

    public List<Page> listChildrenPages(Long parentId) {
        return pageRepository.listChildrenPages(parentId);
    }

    public List<Page> listAllPages() {
        return StreamSupport.stream(pageRepository.findAll().spliterator(), false)
                .collect(Collectors.toList());
    }
}
